const fs = require("fs")
const esprima = require("esprima")
const estraverse = require("estraverse")
const escodegen = require("escodegen")
const iconv = require("iconv-lite")
const base_ast = require("../../tools/es_ast_tool")
const {convertNodesIntoNode} = require("jsdom/lib/jsdom/living/node");


/*
en_jscode -- 包含解密信息的字符串定义
ast -- 要解密的代码 的ast
save_file -- 保存的文件
vars -- 解密字符串变量 yN.substr(836, 8) [yN]
 */
function substr_de(en_jscode, ast, save_file, vars){
    eval(en_jscode);
    estraverse.replace(ast, {
        enter(node, parent){
            if(node.type==="MemberExpression"){
                if(node.object!==undefined&&node.property!==undefined){
                    if(node.object.type==="Identifier"&&node.property.type==="Identifier"){
                        if(node.property.name==="substr"&&vars.includes(node.object.name)){
                            // console.log(escodegen.generate(parent));
                            if (parent && parent.type === "CallExpression") {
                                // 打印父节点代码表示
                                var val = eval(escodegen.generate(parent));
                                console.log(escodegen.generate(parent), val);

                                // 替换父节点为 Literal 字面量节点
                                parent._replaceWithLiteral = val;

                            }
                        }

                    }
                }
            }
        },
        leave(node, parent){
            if (node._replaceWithLiteral!==null&&node._replaceWithLiteral!==undefined) {
                console.log(node._replaceWithLiteral);
                return {
                    type: esprima.Syntax.Literal,
                    value: node._replaceWithLiteral,
                    raw: node._replaceWithLiteral.toString(),
                };
            }
        }
    })

    var new_code = escodegen.generate(ast);
    fs.writeFile(save_file, new_code, (err) => {
    });
}

/*
执行解密函数
en_jscode -- 解密函数代码
ast-- 源代码ast树
en_func_name -- 解密函数名
 */
function call_encrypt(en_jscode, ast, en_func_name){
    //运行解密函数定义
    eval(en_jscode);
    estraverse.replace(ast,{
        enter(node,parent){
            if(node.type==="CallExpression"&&parent.type!=="FunctionDeclaration"){
                if(node.callee&&node.callee.type==="Identifier" && node.callee.name===en_func_name){
                    if(node.arguments&&node.arguments.length===1&&node.arguments[0].type==="Literal"){
                        var code = escodegen.generate(node);
                        console.log(code);
                        var val = eval(code);
                        console.log(val);
                        return {
                            // type: "Literal",
                            type: esprima.Syntax.Literal,
                            value: val,
                            raw: val.toString(),
                        };
                    }

                }
            }
        }
    })
    // base_ast.save_ast_to_file(ast,save_file);
}

module.exports = {
    substr_de,
    call_encrypt
}